#include "../edit/HiliteConfig.h"
#include "unittest.h"

TEST_GROUP (HiliteConfig)
{
}

TEST_CASE (HiliteConfig, test_dif_strings_AddToken) 
{
    CTokens ds;

    TEST_ASSERT(ds.m_uTokenCount == 0);
    TEST_ASSERT(ds.GetCount() == TOKEN_INIT_COUNT);

    int ret;
    char** array;

    ret = ds.AddToken("forward");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 1);
    TEST_ASSERT ( strcmp(array[0], "forward") == 0);

    ret = ds.AddToken("forward");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 1);
    TEST_ASSERT ( strcmp(array[0], "forward") == 0);

    ret = ds.AddToken("backward");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 2);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "forward") == 0);

    ret = ds.AddToken("backward");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 2);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "forward") == 0);

    ret = ds.AddToken("clear");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 3);
    TEST_ASSERT (ds.GetCount() == TOKEN_INIT_COUNT);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "clear") == 0);
    TEST_ASSERT ( strcmp(array[2], "forward") == 0);

    ret = ds.AddToken("clear");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 3);
    TEST_ASSERT (ds.GetCount() == TOKEN_INIT_COUNT);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "clear") == 0);
    TEST_ASSERT ( strcmp(array[2], "forward") == 0);

    ret = ds.AddToken("backward");
    ret = ds.AddToken("forward");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 3);
    TEST_ASSERT (ds.GetCount() == TOKEN_INIT_COUNT);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "clear") == 0);
    TEST_ASSERT ( strcmp(array[2], "forward") == 0);

    ret = ds.AddToken("pencolor");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 4);
    TEST_ASSERT (ds.GetCount() == TOKEN_INIT_COUNT + TOKEN_GROW_STEP);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "clear") == 0);
    TEST_ASSERT ( strcmp(array[2], "forward") == 0);
    TEST_ASSERT ( strcmp(array[3], "pencolor") == 0);

    ret = ds.AddToken("penwidth");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 5);
    TEST_ASSERT (ds.GetCount() == TOKEN_INIT_COUNT + TOKEN_GROW_STEP);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "clear") == 0);
    TEST_ASSERT ( strcmp(array[2], "forward") == 0);
    TEST_ASSERT ( strcmp(array[3], "pencolor") == 0);
    TEST_ASSERT ( strcmp(array[4], "penwidth") == 0);

    ret = ds.AddToken("go");
    array = ds.GetArrayPtr();
    TEST_ASSERT (!ret);
    TEST_ASSERT (ds.m_uTokenCount == 6);
    TEST_ASSERT (ds.GetCount() == TOKEN_INIT_COUNT + TOKEN_GROW_STEP);
    TEST_ASSERT ( strcmp(array[0], "backward") == 0);
    TEST_ASSERT ( strcmp(array[1], "clear") == 0);
    TEST_ASSERT ( strcmp(array[2], "forward") == 0);
    TEST_ASSERT ( strcmp(array[3], "go") == 0);
    TEST_ASSERT ( strcmp(array[4], "pencolor") == 0);
    TEST_ASSERT ( strcmp(array[5], "penwidth") == 0);
}

TEST_CASE (HiliteConfig, test_dif_strings_FindToken) 
{
    CTokens ds;

    ds.AddToken("go");
    ds.AddToken("penwidth");
    ds.AddToken("backward");
    ds.AddToken("forward");
    ds.AddToken("clear");
    ds.AddToken("pencolor");

    unsigned int idx;
    bool found;

    found = ds.FindToken("backward", &idx);
    TEST_ASSERT (found && idx == 0);

    found = ds.FindToken("clear", &idx);
    TEST_ASSERT (found && idx == 1);

    found = ds.FindToken("forward", &idx);
    TEST_ASSERT (found && idx == 2);

    found = ds.FindToken("go", &idx);
    TEST_ASSERT (found && idx == 3);

    found = ds.FindToken("pencolor", &idx);
    TEST_ASSERT (found && idx == 4);

    found = ds.FindToken("penwidth", &idx);
    TEST_ASSERT (found && idx == 5);

    found = ds.FindToken("penup", &idx);
    TEST_ASSERT (!found && (idx == 4 || idx ==5));
}

/* Testcases for CSyntaxConfig ****************************************/
TEST_CASE (HiliteConfig, test_syntaxconfig_SetDelimiters)
{
    CSyntaxConfig syn;
    syn.SetDelimiters("hello");
    TEST_ASSERT (strcmp(syn.m_Delimiter, "hello") == 0);

    syn.SetDelimiters("");
    TEST_ASSERT (strcmp(syn.m_Delimiter, "") == 0);
}

/* Testcases for CSyntaxArray ****************************************/
TEST_CASE (HiliteConfig, test_syntaxarray_AddNewSyntax) 
{
    CSyntaxConfigArray arr;

    TEST_ASSERT (arr.m_uSyntaxCount == 0);
    TEST_ASSERT (arr.GetCount() == SYNTAX_INIT);

    int idx;
    idx = arr.AddNewSyntax();
    TEST_ASSERT (idx == 0 && (arr.GetArrayPtr())[idx] != NULL && arr.GetCount() == SYNTAX_INIT);

    idx = arr.AddNewSyntax();
    TEST_ASSERT (idx == 1 && (arr.GetArrayPtr())[idx] != NULL && arr.GetCount() == SYNTAX_INIT);

    idx = arr.AddNewSyntax();
    TEST_ASSERT (idx == 2 && (arr.GetArrayPtr())[idx] != NULL && arr.GetCount() == SYNTAX_INIT);

    idx = arr.AddNewSyntax();
    TEST_ASSERT (idx == 3 && (arr.GetArrayPtr())[idx] != NULL && arr.GetCount() == SYNTAX_INIT+SYNTAX_GROW);
}

TEST_CASE (HiliteConfig, test_syntaxarray_FindSyntaxByFileExtension)
{
    CSyntaxConfigArray arr;

    CSyntaxConfig* syn;

    int i = arr.AddNewSyntax();
    syn = (arr.GetArrayPtr())[i];
    syn->m_FileExtension.AddToken("c");
    syn->m_FileExtension.AddToken("cpp");
    syn->m_FileExtension.AddToken("h");

    i = arr.AddNewSyntax();
    syn = (arr.GetArrayPtr())[i];
    syn->m_FileExtension.AddToken("logo");
    syn->m_FileExtension.AddToken("lg");

    i = arr.AddNewSyntax();
    syn = (arr.GetArrayPtr())[i];
    syn->m_FileExtension.AddToken("java");

    i = arr.AddNewSyntax();
    syn = (arr.GetArrayPtr())[i];
    syn->m_FileExtension.AddToken("perl");
    syn->m_FileExtension.AddToken("prl");

    unsigned int dummy;
    i = arr.FindSyntaxByFileExtension("java", &syn);
    TEST_ASSERT (i == 2 && syn->m_FileExtension.FindToken("java", &dummy));

    i = arr.FindSyntaxByFileExtension("prl", &syn);
    TEST_ASSERT (i == 3 && syn->m_FileExtension.FindToken("prl", &dummy) &&
        syn->m_FileExtension.FindToken("perl", &dummy));

    i = arr.FindSyntaxByFileExtension("perl", &syn);
    TEST_ASSERT (i == 3 && syn->m_FileExtension.FindToken("prl", &dummy) &&
        syn->m_FileExtension.FindToken("perl", &dummy));

    i = arr.FindSyntaxByFileExtension("lg", &syn);
    TEST_ASSERT (i == 1 && syn->m_FileExtension.FindToken("lg", &dummy) &&
        syn->m_FileExtension.FindToken("logo", &dummy));
    i = arr.FindSyntaxByFileExtension("logo", &syn);
    TEST_ASSERT (i == 1 && syn->m_FileExtension.FindToken("lg", &dummy) &&
        syn->m_FileExtension.FindToken("logo", &dummy));

    i = arr.FindSyntaxByFileExtension("c", &syn);
    TEST_ASSERT (i == 0 && syn->m_FileExtension.FindToken("c", &dummy) &&
        syn->m_FileExtension.FindToken("h", &dummy) && syn->m_FileExtension.FindToken("cpp", &dummy));
    i = arr.FindSyntaxByFileExtension("cpp", &syn);
    TEST_ASSERT (i == 0 && syn->m_FileExtension.FindToken("c", &dummy) &&
        syn->m_FileExtension.FindToken("h", &dummy) && syn->m_FileExtension.FindToken("cpp", &dummy));

    i = arr.FindSyntaxByFileExtension("python", &syn);
    TEST_ASSERT(i == -1 && syn == NULL);
}

TEST_CASE (HiliteConfig, test_syntaxarray_ReadFromFile)
{
    CSyntaxConfigArray arr;
    
    arr.ReadFromFile("syntax.hilight");
    TEST_ASSERT (arr.m_uSyntaxCount == 2);
    
    CSyntaxConfig* syn;
    unsigned int dummy;
    int i = arr.FindSyntaxByFileExtension("lg", &syn);
    TEST_ASSERT (i == 0);
    bool found = syn->m_Keywords.FindToken("not", &dummy);
    TEST_ASSERT(found);
    TEST_ASSERT (strcmp (syn->m_Delimiter, "~!@$%^&*()-+=|\\/{}[]:;\"'<> ,\t.?") == 0);
    TEST_ASSERT (syn->m_BlockCommentOn == NULL);
    TEST_ASSERT (syn->m_BlockCommentOff == NULL);
    TEST_ASSERT (strcmp (syn->m_LineComment, "#") == 0);
    found = syn->m_Indent.FindToken("[", &dummy);
    TEST_ASSERT (found);
    found = syn->m_Unindent.FindToken("]", &dummy);
    TEST_ASSERT (found);
    TEST_ASSERT (syn->m_Keywords.m_uTokenCount == 50);
    TEST_ASSERT (syn->m_Escape == '\0');
    TEST_ASSERT (strcmp (syn->m_Quote, "\"") == 0);

    i = arr.FindSyntaxByFileExtension("java", &syn);
    TEST_ASSERT (i == 1);
    found = syn->m_Keywords.FindToken("while", &dummy);
    TEST_ASSERT(found);
    TEST_ASSERT (strcmp (syn->m_Delimiter, "~!@%^&*()-+=|\\/{}[]:;\"'<> ,\t.?") == 0);
    found = syn->m_Indent.FindToken("{", &dummy);
    TEST_ASSERT (found);
    found = syn->m_Unindent.FindToken("}", &dummy);
    TEST_ASSERT (strcmp(syn->m_LineComment, "//") == 0);
    TEST_ASSERT (strcmp(syn->m_BlockCommentOn, "/*") == 0);
    TEST_ASSERT (strcmp(syn->m_BlockCommentOff, "*/") == 0);
    TEST_ASSERT (syn->m_Keywords.m_uTokenCount == 49);
    TEST_ASSERT (syn->m_Escape == '\\');
    TEST_ASSERT (strcmp (syn->m_Quote, "\"'") == 0);
}

TEST_CASE (HiliteConfig, test_syntaxarray_FindSyntaxByFilename)
{
    CSyntaxConfigArray arr;
    CSyntaxConfig* syn;
    
    arr.ReadFromFile("syntax.hilight");
    TEST_ASSERT (arr.m_uSyntaxCount == 2);
    
    int i = arr.FindSyntaxByFilename("c:\\test\\hello.logo", &syn);
    TEST_ASSERT (i == 0);
    TEST_ASSERT (syn != NULL);

    i = arr.FindSyntaxByFilename("d:\\a.java", &syn);
    TEST_ASSERT (i == 1);
    TEST_ASSERT (syn != NULL);

    i = arr.FindSyntaxByFilename("d:\\a.c", &syn);
    TEST_ASSERT (i == -1);
    TEST_ASSERT (syn == NULL);

    i = arr.FindSyntaxByFilename("a", &syn);
    TEST_ASSERT (i == -1);
    TEST_ASSERT (syn == NULL);
}

TEST_CASE (HiliteConfig, test_GetWordFromFile)
{
    char buf[16];
    FILE* f = fopen("word_test.txt", "rb");
    TEST_ASSERT (f);
    int ret;
    
    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "hello") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "world") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "tt") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "j") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "l") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "yyyyyyyyyyyyyyy") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "yy") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "*") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "&") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, ")") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "hh") == 0);

    memset(buf, 0, sizeof (buf));
    ret = GetStringFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret >= 0 && strcmp(buf, "RRRRRRRRR\tRR R") == 0);

    ret = GetWordFromFile(f, buf, sizeof(buf));
    TEST_ASSERT (ret < 0 );
    fclose (f);
}

TEST_CASE (HiliteConfig, test_GetSyntaxFieldsID)
{
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, LANG_STR) == LANG_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, FILEEXT_STR) == FILEEXT_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, DELIMITER_STR) == DELIMITER_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, INDENT_STR) == INDENT_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, UNINDENT_STR) == UNINDENT_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, BCOMMENTON_STR) == BCOMMENTON_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, BCOMMENTOFF_STR) == BCOMMENTOFF_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, LCOMMENT_STR) == LCOMMENT_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, KEYWORD_STR) == KEYWORD_ID);
    TEST_ASSERT (GetSyntaxFieldsID(g_SyntaxFields, "/language") == OTHER_ID);
}

